library IEEE;
use IEEE.std_logic_1164.all;

package global_definition is
    -- globals
    constant width : natural := 16;

    -- register file definitions
    constant regfile_depth        : positive := 16;
    constant regfile_address_size : positive := 4;  --log2(depth)

    -- memory definitions
    constant ram_address_width : positive := 16;
    constant ram_data_width    : positive := 16;

    -- cache definitions
    constant cache_index_width : positive := 5;
    constant cache_count       : positive := 32;

    --op
    constant OP_ADDIU  : std_ulogic_vector(5 downto 0) := "000001";
    constant OP_ADDIU3 : std_ulogic_vector(5 downto 0) := "000010";
    constant OP_ADDSP3 : std_ulogic_vector(5 downto 0) := "000011";
    constant OP_ADDSP  : std_ulogic_vector(5 downto 0) := "000100";
    constant OP_ADDU   : std_ulogic_vector(5 downto 0) := "000101";
    constant OP_AND    : std_ulogic_vector(5 downto 0) := "000110";
    constant OP_B      : std_ulogic_vector(5 downto 0) := "000111";
    constant OP_BEQZ   : std_ulogic_vector(5 downto 0) := "001000";
    constant OP_BNEZ   : std_ulogic_vector(5 downto 0) := "001001";
    constant OP_BTEQZ  : std_ulogic_vector(5 downto 0) := "001010";
    constant OP_BTNEZ  : std_ulogic_vector(5 downto 0) := "001011";
    constant OP_CMP    : std_ulogic_vector(5 downto 0) := "001100";
    constant OP_CMPI   : std_ulogic_vector(5 downto 0) := "001101";
    constant OP_INT    : std_ulogic_vector(5 downto 0) := "001110";
    constant OP_JALR   : std_ulogic_vector(5 downto 0) := "001111";
    constant OP_JR     : std_ulogic_vector(5 downto 0) := "010000";
    constant OP_JRRA   : std_ulogic_vector(5 downto 0) := "010001";
    constant OP_LI     : std_ulogic_vector(5 downto 0) := "010010";
    constant OP_LW     : std_ulogic_vector(5 downto 0) := "010011";
    constant OP_LW_SP  : std_ulogic_vector(5 downto 0) := "010100";
    constant OP_MFIH   : std_ulogic_vector(5 downto 0) := "010101";
    constant OP_MFPC   : std_ulogic_vector(5 downto 0) := "010110";
    constant OP_MOVE   : std_ulogic_vector(5 downto 0) := "010111";
    constant OP_MTIH   : std_ulogic_vector(5 downto 0) := "011000";
    constant OP_MTSP   : std_ulogic_vector(5 downto 0) := "011001";
    constant OP_NEG    : std_ulogic_vector(5 downto 0) := "011010";
    constant OP_NOT    : std_ulogic_vector(5 downto 0) := "011011";
    constant OP_OR     : std_ulogic_vector(5 downto 0) := "011100";
    constant OP_SLL    : std_ulogic_vector(5 downto 0) := "011101";
    constant OP_SLLV   : std_ulogic_vector(5 downto 0) := "011110";
    constant OP_SLT    : std_ulogic_vector(5 downto 0) := "011111";
    constant OP_SLTI   : std_ulogic_vector(5 downto 0) := "100000";
    constant OP_SLTU   : std_ulogic_vector(5 downto 0) := "100001";
    constant OP_SLTUI  : std_ulogic_vector(5 downto 0) := "100010";
    constant OP_SRA    : std_ulogic_vector(5 downto 0) := "100011";
    constant OP_SRAV   : std_ulogic_vector(5 downto 0) := "100100";
    constant OP_SRL    : std_ulogic_vector(5 downto 0) := "100101";
    constant OP_SRLV   : std_ulogic_vector(5 downto 0) := "100110";
    constant OP_SUBU   : std_ulogic_vector(5 downto 0) := "100111";
    constant OP_SW     : std_ulogic_vector(5 downto 0) := "101000";
    constant OP_SW_RS  : std_ulogic_vector(5 downto 0) := "101001";
    constant OP_SW_SP  : std_ulogic_vector(5 downto 0) := "101010";
    constant OP_XOR    : std_ulogic_vector(5 downto 0) := "101011";
    constant OP_NOP    : std_ulogic_vector(5 downto 0) := "000000";
    constant OP_ERROR  : std_ulogic_vector(5 downto 0) := "000000";
    constant OP_INT1   : std_ulogic_vector(5 downto 0) := "101100";
    constant OP_INT2   : std_ulogic_vector(5 downto 0) := "101101";
    constant OP_INT3   : std_ulogic_vector(5 downto 0) := "101110";

    --reg addr
    constant RegAddr_R0 : std_ulogic_vector(3 downto 0) := "0000";
    constant RegAddr_R1 : std_ulogic_vector(3 downto 0) := "0001";
    constant RegAddr_R2 : std_ulogic_vector(3 downto 0) := "0010";
    constant RegAddr_R3 : std_ulogic_vector(3 downto 0) := "0011";
    constant RegAddr_R4 : std_ulogic_vector(3 downto 0) := "0100";
    constant RegAddr_R5 : std_ulogic_vector(3 downto 0) := "0101";
    constant RegAddr_R6 : std_ulogic_vector(3 downto 0) := "0110";
    constant RegAddr_R7 : std_ulogic_vector(3 downto 0) := "0111";

    constant RegAddr_T  : std_ulogic_vector(3 downto 0) := "1000";
    constant RegAddr_SP : std_ulogic_vector(3 downto 0) := "1001";
    constant RegAddr_RA : std_ulogic_vector(3 downto 0) := "1010";
    constant RegAddr_IH : std_ulogic_vector(3 downto 0) := "1011";

    --alu op
    constant ALUOP_ADD   : std_ulogic_vector(3 downto 0) := "0000";
    constant ALUOP_SUB   : std_ulogic_vector(3 downto 0) := "0001";
    constant ALUOP_AND   : std_ulogic_vector(3 downto 0) := "0010";
    constant ALUOP_OR    : std_ulogic_vector(3 downto 0) := "0011";
    constant ALUOP_XOR   : std_ulogic_vector(3 downto 0) := "0100";
    constant ALUOP_LESSU : std_ulogic_vector(3 downto 0) := "0101";
    constant ALUOP_LESS  : std_ulogic_vector(3 downto 0) := "0110";
    constant ALUOP_SLL   : std_ulogic_vector(3 downto 0) := "0111";
    constant ALUOP_SRA   : std_ulogic_vector(3 downto 0) := "1000";
    constant ALUOP_SRL   : std_ulogic_vector(3 downto 0) := "1001";
    constant ALUOP_NOT   : std_ulogic_vector(3 downto 0) := "1010";
    constant ALUOP_NEG   : std_ulogic_vector(3 downto 0) := "1011";
    constant ALUOP_REG1  : std_ulogic_vector(3 downto 0) := "1100";
    constant ALUOP_REG2  : std_ulogic_vector(3 downto 0) := "1101";
    constant ALUOP_SUB2  : std_ulogic_vector(3 downto 0) := "1110";  -- out = r1 -2

    --mem op
    constant MEMOP_NONE  : std_ulogic_vector(1 downto 0) := "00";
    constant MEMOP_READ  : std_ulogic_vector(1 downto 0) := "01";
    constant MEMOP_WRITE : std_ulogic_vector(1 downto 0) := "10";
    
end package;
